package depta;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.htmlparser.Node;
import org.htmlparser.NodeFactory;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.lexer.Lexer;
import org.htmlparser.lexer.Page;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import wish.stages.ParsingStage;
import depta.dataregion.DataRegion;
import depta.dataregion.MDR2;
import depta.dataregion.finder.DataRegionFinder;
import evaluation.results.SizeFilter;

public class Depta {


	
	public static void main(String[] args) throws IOException {

		new Depta().start();
		
	}

	private void start() throws IOException {
		
		String type = "training";
		
//		System.setErr(null);
		
//		double[] thresholdA = {0.15,0.1,0.20,0.25,0.05};
//		double[] thresholdA = {0.35,0.30,0.40,0.25,0.45};
		
		String folder = "/proj/dbNoBackup/pjbarrio/Experiments/Wrappers/QueryResults/" + type + "/";
		
		String outpF = "/proj/dbNoBackup/pjbarrio/Experiments/Wrappers/DEPTA/" + type + "/";
		
		String sizeSorted = "/proj/dbNoBackup/pjbarrio/Experiments/Wrappers/SizeSortedList/" + type + "/";
		
		int number = 1;
		
		File folders = new File(folder);
		
		File[] databaseFolders = folders.listFiles();
		
		double[] thresholdA = {0.4};

		int[] K = {10};
		
		for (int i = 0; i < databaseFolders.length; i++) {
			
			System.out.println("DATABASE: " + i);
			
			String name = databaseFolders[i].getName();
			
			File outputFolder = new File(outpF,name);

			if (outputFolder.exists())
				continue;
			
			outputFolder.mkdir();
			
			File[] pages = databaseFolders[i].listFiles(new SizeFilter(new File(sizeSorted,name + ".list"),number));
							
			for (int j = 0; j < pages.length; j++) {
				
				System.gc();
				
				System.out.println("FILE: " + j);
				
				File outputPage = new File(outputFolder,pages[j].getName());

				for (int t = 0; t < thresholdA.length; t++) {
					
					double threshold = thresholdA[t];
					
					for (int kind = 0; kind < K.length; kind++) {
						
						int kval = K[kind];
												
						new Depta().execute(pages[j],kval,threshold,outputPage);
						
					}
								
				}
				
			}
			
		}

		
		
	}

	private class DDR implements Runnable{

		private File file;
		private int K;
		private double threshold;
		private File outp;

		public DDR(File file, int k, double threshold, File outp) {
			this.file = file;
			this.K = k;
			this.threshold = threshold;
			this.outp = outp;
		}

		@Override
		public void run() {

			try {

				List<DataRegion> drs = detectDataRegions(file,K,threshold);

				BufferedWriter bw = new BufferedWriter(new FileWriter(outp));

				for (DataRegion dataRegion : drs) {

					bw.write("\n<h1> DATA REGION: </h1>\n");

					bw.write(dataRegion.toString());

					bw.newLine();

				}

				bw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParserException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}
	
	private void execute(File file, int K, double threshold, File outp) {
		
		Thread t = new Thread(new DDR(file,K,threshold,outp));
		
		t.start();
		
		try {
			t.join(50000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private List<DataRegion> detectDataRegions(File file,int K, double threshold) throws IOException, ParserException {
		
		System.gc();
		
		String htmlContent = ParsingStage.readFile(file);
		
		Parser parser = new Parser(new Lexer(new Page(htmlContent, "UTF-8")));
		
		NodeIterator ni =parser.elements();
		
		TagNode n = new TagNode();
		
		n.setTagName("Root");
		
		NodeList child = new NodeList();
		
		while(ni.hasMoreNodes()){
			
			Node kid = ni.nextNode();
			
			kid.setParent(n);
			
			child.add(kid);
		}
		
		n.setChildren(child);
				
		System.out.println("Parsed...");
		
		MDR2 mdr2 = new MDR2();
		
		mdr2.MDR2Algorithm(n, K);
		
		System.out.println("MDR2ed...");
		
		DataRegionFinder drf = new DataRegionFinder(mdr2, K, threshold);
		
		System.out.println("DRFound...");
		
		return drf.findDRs(n);
		
	}


}
